package cn.tedu.alipay.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayOpenPublicTemplateMessageIndustryModifyRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayOpenPublicTemplateMessageIndustryModifyResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("alipay")
public class AlipayController {

/*

    APP_ID （appId，从沙箱管理页面获得）

    APP_PRIVATE_KEY （应用私钥，最开始在密钥工具生成而来）

    ALIPAY_PUBLIC_KEY （支付宝公钥，上一步骤获得）

    GATEWAY_URL （支付宝网关地址，在开发平台沙箱管理页面中获得）

    SIGN_TYPE （签名类型）

    NOTIFY_URL （异步回调地址，须是公网IP，后面再解释）

    RETURN_URL （同步回调地址，可以是私网IP
*/

 /*   @Autowired
    DonaItemService donaItemService;
    @Autowired
    DonaService donaService;*/
    //appid
    private final String APP_ID = "2021000120618018";
    //应用私钥
    private final String APP_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCgLGLeXh1dVPCQw8VCGy/1SfOkBFtZxACS81NkmtTX4DGVxVeDb361QHDaIjzk30Oz0vKZ8WCFl+w/IOr1Rz6HODQJFliu3dak+On+cwzeu+dx5nelmsGlYHVptgiblAp6wBZaF+6RvF5GFIar/VGEfswMsRFC20jG7LaY1kUSpdnESlAjdTg/rfbbZROEELbVfklvvbJQBz2rgKgAAhw5fxXkMsbeJbVN8ZZO1tlSSm/22VmRs3UJbnqnyIwzckgXYyXn5x2Oujjvu1DAFnOeL0e6vkzDuj9lJH+8BI0D44P/MXcFmhifLAMOISNcQCk5FVes2YHI6Cyjw7wT34qhAgMBAAECggEAWpwBai3viqbMV/iHlHfwz2AAVh6o1sUMVhUUbesw0NZg9ormkNH36e0EakHIFOlAUW/aEb/8jFZ/LM8gW5TsCG6A8UsU7AdOr5CoPmszMqU1rrdjo+lB9p30jdKOWASNURdtDZZQPV1EL3zZGl55SOy53cwlKZ8HMpEiUp+T/5GxbRC0Plq1wuoAV+G/XpfDQ7iG1Cc4/laV8odIOvDkVdu6E0L1IQzixsovzi5BnRGIJY9gK8l6tQu8X/ol+iTF5iOuFXRR4HsOwXrKhqOkJbgJkd+m3FpBWWRDhnb1j/Lto91Poef5wBqzjzRCS5il9cYlc9U9QEodBY9QajVNaQKBgQDXfCq7q/O5G9SlXXVoQ2ngTXiItO3YyOHEGhq1bPmivspcTJBDQqyzBqbZBGh8/UvIv1P6kACpDnQQPNYJIGtkPHbaMI3Jz9aUKISQYpcYB+qNANAlRdamFq81Pc8JLnZHGfa6pXZE/Cec9ycH18r90YlJEVJPH2WxdXDmsin6mwKBgQC+Se59STUZBB1aQyG1YwuOkeJooTGQGh4cr8InNBuUPQPpyHz9MUIZxZt70GA/gD2M4xavIB/vfyOPcedvwHbZZQAgLbapRE2kcWoD0Xl7pRlwdJ9Hb0w6JIh0B3OejNnC6wl25tj2wXAe7SWnkV0dfqMVg0XJBGm13OHkzBPVcwKBgCHfdOA3cYKBq3WrMU+IeVY3F2F1/4V6XnLzH4uxa7R3hVvo9Sx9iKRDwWqP1NUBBC60VMEobdIlYX1D8ulQXVFOZ+h4hXFZ6IM1s1D3DoVKiUZNAGs7hThqjHQ0GR16XkFjBXPlmqfRc3CrMUl8VH59t7TyshuZ9eRlb6/0BcFNAoGBAICMT0lh2DXzGqUsbqwrodYJZWsLYgEYM7lrXny/bdYhtfAL2avtx9rDLLti1HJxfqMbkepyiEBxoiM4boGHAoLwATq7xwboNo9dcqHrs+a8bMgUcLmATX2FyoyfsBKu0jkkMHubjXx8xvKNf/+IauAO+bsBuHYIviT2d7/pwYhTAoGAEY9bzLSfcB53LOtPWJ4btHWL9Qpe/D2ulmo6WkgLBi4H2wPNk/yUp5wetlVZr1iEA4z40W/Nx4lCitn01rnKXQP4w2UYIlj+aIHp70l09sMaDlimlfMW2HUdIzVxNpaaFEXc5PkWeyxlBHwbys/Qu4OEXNkbcnVpi4LBkypsxOc=";
    private final String CHARSET = "UTF-8";
    // 支付宝公钥
    private final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhoMbVvVsyV0g04seuPZUPqJTUi/LUst6GHKKhxyACisrZOOfDouKqPmRuJX24YfJgfbgQ5IKb6/t0pKW/Kho6znvpIlkZEMjAHuNMQaxtu+bFBzyfxr3P+fkrdUkRg3+z92su/h0whUr/qEv1Z43Gqlt/JCKW4fwIjkn7vZHtjoIvMDseylqLaAfA981zUPMxA7bIeooFhOgL/xYXdvn1qDtO2dV2NsHTeW0/gS29wcUm9m8w9pF5VcjLsi82LaY+ur9XW1DO9U/W87d3tuXd7seSYMw718IgTIOSJ+1tX4/NVUov6bDPCrsBATltcGtN6eM4iH6ix3+ZocSp9DfJQIDAQAB";
    //这是沙箱接口路径,正式路径为https://openapi.alipay.com/gateway.do
    private final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
    private final String FORMAT = "JSON";
    //签名方式
    private final String SIGN_TYPE = "RSA2";
    //支付宝异步通知路径,付款完毕后会异步调用本项目的方法,必须为公网地址
    // private final String NOTIFY_URL = "http://127.0.0.1/notifyUr"l;
    //支付宝同步通知路径,也就是当付款完毕后跳转本项目的页面,可以不是公网地址
    private final String RETURN_URL = "http://localhost:9000/alipay/returnUrl";


    @RequestMapping("success")
    public String alipaySuccess(){
        return "success";
    }

    //必须加ResponseBody注解，否则spring会寻找thymeleaf页面
    @ResponseBody
    @RequestMapping("/payTest1")
   /* public String alipay( Model model,
                         @RequestParam("dona_money") float dona_money,
                         @RequestParam("dona_id") int dona_id) throws AlipayApiException {*/
    public String alipay( ) throws AlipayApiException {
        //把dona_id项目id 放在session中
       // session.setAttribute("dona_id",dona_id);
       float dona_money=1.1f;


        //生成订单号（支付宝的要求？）
        String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String user = UUID.randomUUID().toString().replace("-","").toUpperCase();

        String OrderNum = time+user;

        //调用封装好的方法（给支付宝接口发送请求）
        return sendRequestToAlipay(OrderNum,dona_money,"宝马支付");
    }
    /*
    参数1：订单号
    参数2：订单金额
    参数3：订单名称
 */
    //支付宝官方提供的接口
    private String sendRequestToAlipay(String outTradeNo,Float totalAmount,String subject) throws AlipayApiException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL,APP_ID,APP_PRIVATE_KEY,FORMAT,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(RETURN_URL);
       // alipayRequest.setNotifyUrl(NOTIFY_URL);

        //商品描述（可空）
        String body="测试商品支付";
        /**
         *
        alipayRequest.setBizContent(" {\"out_trade_no\": \" " +outTradeNo + "\","
                + " \"total_amount\":\"" +totalAmount + "\","
                + " \"subject\":\"" +subject +"\","
                + " \"body\": \"" +body + "\","
                + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

         System.out.println(" {\"out_trade_no\": \" "+outTradeNo + "\","
         + " \"total_amount\":\" " +totalAmount + "\","
         + " \"subject\":\" " +subject + "\","
         + " \"body\": \" " +body + "\","
         + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

         */
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("total_amount", totalAmount);
        bizContent.put("subject", subject);
        bizContent.put("boby",body);
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

        alipayRequest.setBizContent(bizContent.toString());




        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        return result;
    }

        /*
        除了需要提供之前设置好的私有属性（URL，公钥，私钥，网关等等）外，还需要提供的参数
        outTradeNo，订单号，必须为String64位，不能为空且不能重复
        totalAmount，支付金额，不能为空
        subject，订单名称，不能为空
        body，商品描述，可以为空
        * */

    @RequestMapping("returnUrl")
    @ResponseBody
    public String returnUrlMethod(HttpServletRequest request, HttpSession session, Model model) throws AlipayApiException, UnsupportedEncodingException
        {
            System.out.println("= 同步回调 =====");

            // 获取支付宝GET过来反馈信息
            Map<String, String> params = new HashMap<String, String>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                // 乱码解决，这段代码在出现乱码时使用
              //  valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }

            System.out.println(params);//查看参数都有哪些
            //验证签名（支付宝公钥）
            boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE); // 调用SDK验证签名
            //验证签名通过
            if(signVerified){
                // 商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

                // 支付宝交易流水号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

                // 付款金额
                float money = Float.parseFloat(new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"));

                System.out.println("商户订单号="+out_trade_no);
                System.out.println("支付宝交易号="+trade_no);
                System.out.println("付款金额="+money);

                //在这里编写自己的业务代码（对数据库的操作）
		/*
		################################
		*/
                //跳转到提示页面（成功或者失败的提示页面）
               // model.addAttribute("flag",1);
               // model.addAttribute("msg","支持");
                return  out_trade_no+":"+trade_no+":"+money;
            }else{
                //跳转到提示页面（成功或者失败的提示页面）
               // model.addAttribute("flag",0);
               // model.addAttribute("msg","支持");
                return "回调失败 支付失败";
            }
        }




    @RequestMapping("payTest")
    public void alipay(HttpServletResponse httpResponse) {

        // 1 实例化客户端
        AlipayClient alipayClient = getAlipayClient();

        //2 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.open.public.template.message.industry.modify
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        //SDK已经封装掉了公共参数，这里只需要传入业务参数
        //此次只是参数展示，未进行字符串转义，实际情况下请转义\


        request.setNotifyUrl("");
        request.setReturnUrl(RETURN_URL);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", "20221029111002202");
        bizContent.put("total_amount", 0.02);
        bizContent.put("subject", "轿车GL651");
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

        request.setBizContent(bizContent.toString());


        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody();


            httpResponse.setContentType("text/html;charset=" + "UTF-8");
            httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
        } catch (Exception e) {
            System.out.println("调用遭遇异常，原因：" + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }

    }

    @RequestMapping("payStatus")
    public void payStatus(HttpServletResponse servletResponse){
        // 1 实例化客户端
        AlipayClient alipayClient = getAlipayClient();

        //2 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.open.public.template.message.industry.modify
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();  // 发送请求的 Request类
        //SDK已经封装掉了公共参数，这里只需要传入业务参数
        //此次只是参数展示，未进行字符串转义，实际情况下请转义\



        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", "202210291110022");
        request.setBizContent(bizContent.toString());

        try {

            while (true) {

                AlipayTradeQueryResponse response = alipayClient.execute(request);
                System.out.println(response.getBody());
                String code = response.getCode();
                Map resultMap = new HashMap();
                if(code!=null&&code.equals("10000")){
                    resultMap.put("trade_no", response.getTradeNo());
                    resultMap.put("out_trade_no", response.getOutTradeNo());
                    resultMap.put("trade_status",response.getTradeStatus());
                }


                if(resultMap.get("teade_status")!=null&&resultMap.get("trade_status").equals("TRADE_SUCCESS")){
                    System.out.println("支付成功");
                    servletResponse.sendRedirect("locahost:9000/alipay/success");
                    break;
                }
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private  AlipayClient getAlipayClient() {
        AlipayConfig alipayConfig = new AlipayConfig();
        //设置网关地址
        alipayConfig.setServerUrl("https://openapi.alipaydev.com/gateway.do");
        //设置应用ID
        alipayConfig.setAppId(APP_ID);

        //设置应用私钥
        alipayConfig.setPrivateKey(APP_PRIVATE_KEY);
        //设置请求格式，固定值json
        alipayConfig.setFormat("json");
        //设置字符集
        alipayConfig.setCharset("utf-8");
        //设置签名类型
        alipayConfig.setSignType("RSA2");
        //设置支付宝公钥
        alipayConfig.setAlipayPublicKey(ALIPAY_PUBLIC_KEY);
        //实例化客户端
        AlipayClient alipayClient=null;
        try {
            alipayClient  = new DefaultAlipayClient(alipayConfig);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return alipayClient;
    }

}
